/**
 * @Author: kesally
 * @Date: 2022-09-24 20:00:00
 * @LastEditTime: 2022-09-24 21:00:00
 * @LastEditors: kesally
 * @Description: 一个用于模仿角色说话的插件
 * @FilePath: \Yunzai-Bot\plugins\example\原神角色语音v3(改-kesally 之前改的报错).js
 * @版权声明
 * @宣传下群不过分吧707499227
 * @修改不易，请勿倒卖
 * @作者QQ2770706493
 **/



import fetch from "node-fetch";
import plugin from '../../lib/plugins/plugin.js'
import gsCfg from '../genshin/model/gsCfg.js'



// 以下三项参数仅对原神音色生效*(若修改需重启云崽生效)
// 生成时使用的 noise_factor，可用于控制感情等变化程度。默认为0.667。
const noise = 0.667
// 生成时使用的 noise_factor_w，可用于控制音素发音长度变化程度。默认为0.8。
const noisew = 0.8
// 生成时使用的 length_factor，可用于控制整体语速。默认为1.2。
const length = 1.3



export class genshinSpeak extends plugin {
  constructor() {
    super({
      /** 功能名称 */
      name: '文字转语音',
      /** 功能描述 */
      dsc: '简单开发示例',
      event: 'message',
      /** 优先级，数字越小等级越高 */
      priority: 6000,
      rule: [
        {
          /** 命令正则匹配 */
          reg: "^#*(.*)说(.*)$",  //匹配消息正则，命令正则
          /** 执行方法 */
          fnc: 'genshinSpeak'
        },
        {
          /** 命令正则匹配 */
          reg: '^#*音色列表$',
          /** 执行方法 */
          fnc: 'speakerList'
        }
      ]


    })
  }

  async genshinSpeak(e) {
    // 提取发言人和发言内容
    let data = e.msg.split("#").slice(-1)[0].split("说")
    while (data.length > 2) {
      data[1] = data[1].concat("说").concat(data[2])
      data.splice(2, 1)
    }

    // 如果发言内容或发言人为空则返回
    if (!data[1] || !data[0])
      return false

    let nameArr = gsCfg.getAllAbbr()
    for (let rolename of Object.values(nameArr)) {
      // console.log(rolename)
      if (rolename.includes(data[0])) {
        data[0] = rolename[0]
        break
      }
    }

    // 原神音色
    if (genshinSpeakers.includes(data[0])) {
      // 原神语音接口不支持阿拉伯数字,所以将数字转为汉字
      let text = data[1].split("")
      const num = { "1": "一", "2": "二", "3": "三", "4": "四", "5": "五", "6": "六", "7": "七", "8": "八", "9": "九", "0": "零" }
      for (let i = 0; i < text.length; i++) {
        if ((/\d/g).test(text[i]))
          text[i] = num[text[i]]
      }
      data[1] = text.join("")

      console.log("【语音合成】 \n【音色】:", data[0], "\n【内容】:", data[1])
      e.reply([segment.record(`http://233366.proxy.nscc-gz.cn:8888/?text=${encodeURI(data[1])}&speaker=${encodeURI(data[0])}&noise=${noise}&noisew=${noisew}&length=${length}`)])
      return true
    }

    // 其他音色
    else if (Object.keys(otherSpeakers).includes(data[0])) {
      console.log("【语音合成】 \n【音色】:", data[0], "\n【内容】:", data[1])
      e.reply([segment.record(`https://dds.dui.ai/runtime/v1/synthesize?voiceId=${otherSpeakers[data[0]]}&text=${encodeURI(data[1])}&speed=1&volume=150&audioType=wav`)])
      return true
    }

    // 柚子社音色
    else if (Object.keys(youziSpeakers).includes(data[0])) {
      // 翻译为日语
      let jptxt = await fetch(`http://www.iinside.cn:7001/api_req?reqmode=nmt_mt5_jez&password=3652&text=${encodeURI(data[1])}&order=zh2ja`)
      jptxt = await jptxt.json();
      console.log("【语音合成】 \n【音色】:", data[0], "\n【原文】:", data[1], "\n【译文】:", jptxt.data)

      let url = `https://moegoe.azurewebsites.net/api/speak?text=${encodeURI(jptxt.data)}&id=${youziSpeakers[data[0]]}&format=mp3`;
      console.log(url)
      e.reply(["正在转换,请稍等~"]);

      try {
        let res = await fetch(url);
        // console.log(res)
        if (res.status == 400) {
          e.reply("转换失败")
          return true
        }
        console.log(res.url)
        e.reply(segment.record(res.url))
      } catch (error) {
        e.reply([segment.text(error)])
      }
      return true
    }
    // 未匹配到则放行指令
    else
      return false
  }

  async speakerList(e) {
    e.reply(["原神音色，支持别称:\n", segment.text(genshinSpeakers), "\n\n柚子社音色:\n", segment.text(Object.keys(youziSpeakers)), "\n\n其他音色:\n", segment.text(Object.keys(otherSpeakers)), "\n\n格式: 音色+说+要说的话"])
    return true
  }
}





